import { ref, onMounted, nextTick, inject, toRaw } from 'vue';
import { hasClass } from '@jecloud/utils';
import Sortable from 'sortablejs';
import { dragClass, dragGroup, dragGhostClass, provideDrag, draggableClass } from './config';

export function useDraggable({ owner, props }) {
  const dragEl = ref();
  const { refreshData } = inject(provideDrag);
  // 删除元素
  const removeFn = function () {
    refreshData({ action: 'remove', owner, evt: { item: props.data } });
  };
  // 绑定拖拽
  if (['group', 'container'].includes(owner)) {
    onMounted(() => {
      nextTick(() => {
        new Sortable(dragEl.value.$el ?? dragEl.value, {
          filter: '.filter',
          handle: '.' + dragClass,
          ghostClass: dragGhostClass,
          group: dragGroup,
          onMove: function (evt) {
            let formId = evt.dragged.getAttribute('data-id');
            let toId = evt.to.getAttribute('data-id');

            if (toId) {
              if (Array.isArray(props.data)) {
                let data = props.data.find((ri) => ri.id === formId);
                if (['workflowhistory', 'child'].includes(data.RESOURCEFIELD_XTYPE) && toId) {
                  return false;
                }
              }
            }

            const target = evt.originalEvent.target;
            // 判断拖拽有效区域
            return (
              hasClass(target, 'container-field') ||
              hasClass(target, 'group-header') ||
              hasClass(target, 'group-body') ||
              hasClass(target, 'container')
            );
          },
          onAdd: function (evt) {
            refreshData({ action: 'add', owner, evt });
            //获取拖动后的排序
          },
          onUpdate: function (evt) {
            refreshData({ action: 'sort', owner, evt });
            //获取拖动后的排序
          },
        });
      });
    });
  }

  return { removeFn, dragEl, dragClass, draggableClass };
}

/**
 * 计算排序
 * @param {*} parent
 * @param {*} groupId
 * @returns
 */
const doSort = function (parent, groupId, index = 0) {
  let data = {};
  const selecter = ':scope > [data-type][data-id]';

  // 添加分组数据
  if (parent.getAttribute('data-type') === 'group') {
    const groupBody = parent.querySelector('.group-body');
    // 拖入的元素没有group样式
    parent = groupBody ?? parent;
  }

  // 子数据
  const doms = parent.querySelectorAll(selecter);
  doms.forEach((dom) => {
    const id = dom.getAttribute('data-id');
    const type = dom.getAttribute('data-type');
    data[id] = { id, groupId, index: index++ };
    if (type === 'group') {
      const groupData = doSort(dom, id, index);
      index += Object.keys(groupData).length;
      Object.assign(data, groupData);
    }
  });
  return data;
};
/**
 * 级联跟新组内数据显隐
 * @param {*} data
 * @param {*} groupId
 * @param {*} visible
 */
function setGroupVisible(data, groupId, visible) {
  data.forEach((item) => {
    if (item.groupId === groupId) {
      item.hidden = !visible;
      if (item.type === 'group') {
        setGroupVisible(data, item.id, visible);
      }
    }
  });
}

/**
 * 操作后，进行数据刷新
 * @param {*} param0
 */
export function refreshData({ info, evt, action, containerEl }) {
  const { item, target } = evt;
  const rawData = toRaw(info.data);

  let id = '';
  let groupId = '';
  let addItem = {};
  let removeItem = {};

  switch (action) {
    case 'add':
      id = item.getAttribute('data-id');
      groupId = target.getAttribute('data-id');
      addItem = rawData.find((ri) => ri.id === id);

      if (groupId) {
        addItem.groupId = groupId;
        addItem.RESOURCEFIELD_GROUPNAME = groupId;
      }

      Object.assign(addItem, {
        hidden: false,
        groupId,
      });
      setGroupVisible(rawData, id, true);
      break;
    case 'remove':
      removeItem = rawData.find((ri) => ri.id === item.id);

      removeItem.groupId = '';
      removeItem.RESOURCEFIELD_GROUPNAME = '';

      removeItem.hidden = true;
      setGroupVisible(rawData, removeItem.id, false);
      break;
  }

  // 所有操作后都需要重新排序，减少逻辑处理

  // 排序后的显示数据
  let sortData = {};

  if (action === 'remove') {
    // 删除操作，当前字段的 dom 被从 .container 中移除，重新排序
    let el = containerEl.value.$el.querySelector(`div[data-id='${item.id}']`);
    el.parentNode.removeChild(el);
    sortData = doSort(containerEl.value.$el);
  } else {
    // 添加操作，排序
    sortData = doSort(containerEl.value.$el);
  }

  // 隐藏字段索引
  let hiddenStartIndex = Object.keys(sortData).length;

  // 更新数据
  info.data = rawData
    .map((rd) => {
      return Object.assign(rd, sortData[rd.id] || { index: hiddenStartIndex++ });
    })
    .sort((a, b) => a.index - b.index);
}
